<template>
  <div class="offline-analysis">
    <!-- 任务管理平台 -->
    <el-card class="box-card" style="margin-bottom: 20px;">
      <div slot="header" class="clearfix">
        <span>任务管理平台</span>
        <el-button type="primary" size="small" style="float: right;" @click="showCreateTask = true">创建任务</el-button>
      </div>
      <el-table :data="taskList" style="width: 100%;" size="small">
        <el-table-column prop="name" label="任务名称" width="180"/>
        <el-table-column prop="createdAt" label="创建时间" width="180"/>
        <el-table-column prop="status" label="状态" width="100">
          <template slot-scope="scope">
            <el-tag :type="statusTagType(scope.row.status)" size="mini">{{ scope.row.status }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="progress" label="进度" width="120">
          <template slot-scope="scope">
            <el-progress :percentage="scope.row.progress" :status="progressStatus(scope.row.status)" :stroke-width="12" />
          </template>
        </el-table-column>
        <el-table-column label="操作" width="120">
          <template slot-scope="scope">
            <el-button type="text" size="mini" @click="editTask(scope.row)">编辑</el-button>
            <el-button type="text" size="mini" @click="deleteTask(scope.row.id)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!-- 创建/编辑任务弹窗 -->
    <el-dialog :title="editTaskId ? '编辑任务' : '创建任务'" :visible.sync="showCreateTask" width="600px" @close="resetTaskForm">
      <el-form :model="taskForm" label-width="120px" :rules="taskRules" ref="taskForm">
        <el-form-item label="任务名称" prop="name">
          <el-input v-model="taskForm.name" placeholder="请输入任务名称"/>
        </el-form-item>
        <el-form-item label="上传Python脚本" prop="script">
          <el-upload
            class="upload-demo"
            drag
            :auto-upload="false"
            :show-file-list="true"
            :on-change="handleScriptUpload"
            :file-list="taskForm.script ? [taskForm.script] : []"
            accept=".py"
          >
            <i class="el-icon-upload"></i>
            <div class="el-upload__text">将Python脚本拖到此处，或<em>点击上传</em></div>
          </el-upload>
        </el-form-item>
        <el-form-item label="Executor数量" prop="executors">
          <el-slider v-model="taskForm.executors" :min="4" :max="16" :step="1" show-input style="width: 80%;"/>
        </el-form-item>
        <el-form-item label="内存配置" prop="memory">
          <el-slider v-model="taskForm.memory" :min="8" :max="32" :step="1" show-input style="width: 80%;" :format-tooltip="val => val + 'GB'"/>
        </el-form-item>
        <el-form-item label="计算框架" prop="framework">
          <el-select v-model="taskForm.framework" placeholder="请选择">
            <el-option label="MapReduce" value="MapReduce"/>
            <el-option label="SparkSQL" value="SparkSQL"/>
          </el-select>
        </el-form-item>
        <el-form-item label="数据分片">
          <el-switch v-model="taskForm.enableSharding"/>
          <span style="margin-left: 10px;">每片1GB</span>
        </el-form-item>
        <el-form-item label="定时调度" prop="schedule">
          <el-time-picker
            v-model="taskForm.schedule"
            is-range
            arrow-control
            range-separator="至"
            start-placeholder="开始时间"
            end-placeholder="结束时间"
            placeholder="选择每日执行时间段"
            :picker-options="{ selectableRange: '00:00:00 - 23:59:59' }"
            style="width: 100%;"
          />
          <div style="font-size: 12px; color: #888;">如每日凌晨2点执行，选择 02:00:00 - 02:30:00</div>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="showCreateTask = false">取 消</el-button>
        <el-button type="primary" @click="submitTaskForm">确 定</el-button>
      </div>
    </el-dialog>

    <!-- 算法配置 -->
    <el-card class="box-card" style="margin-bottom: 20px;">
      <div slot="header" class="clearfix">
        <span>算法配置</span>
      </div>
      <el-form :model="algoConfig" label-width="120px" :inline="true" style="margin-bottom: 10px;">
        <el-form-item label="聚类算法">
          <el-select v-model="algoConfig.method" disabled>
            <el-option label="K-Means" value="K-Means"/>
          </el-select>
        </el-form-item>
        <el-form-item label="聚类数K">
          <el-input-number v-model="algoConfig.k" :min="2" :max="10"/>
        </el-form-item>
        <el-form-item label="迭代次数">
          <el-input-number v-model="algoConfig.iterations" :min="1" :max="100"/>
        </el-form-item>
        <el-form-item label="输入字段">
          <el-checkbox-group v-model="algoConfig.fields">
            <el-checkbox label="电流"/>
            <el-checkbox label="电压"/>
            <el-checkbox label="运行时长"/>
          </el-checkbox-group>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="runAnalysis" :loading="analyzing">执行分析</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <!-- 结果可视化 -->
    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <span>结果可视化</span>
        <el-button type="primary" size="small" style="float: right;" @click="exportReport" :disabled="!analysisResult">导出报告</el-button>
      </div>
      <div v-if="analysisResult">
        <div style="display: flex; flex-wrap: wrap;">
          <div style="flex: 1; min-width: 350px;">
            <div style="font-weight: bold; margin-bottom: 10px;">能耗高峰期分布热力图</div>
            <div ref="heatmap" style="width: 100%; height: 300px;"></div>
          </div>
          <div style="flex: 1; min-width: 350px;">
            <div style="font-weight: bold; margin-bottom: 10px;">年均故障高发期预测（置信度分析）</div>
            <el-table :data="analysisResult.confidence" size="small" style="width: 100%;">
              <el-table-column prop="month" label="月份" width="80"/>
              <el-table-column prop="faults" label="预测故障数" width="120"/>
              <el-table-column prop="confidence" label="置信度" width="120">
                <template slot-scope="scope">
                  <el-progress :percentage="scope.row.confidence" :text-inside="true" :stroke-width="18"/>
                </template>
              </el-table-column>
            </el-table>
          </div>
        </div>
      </div>
      <div v-else style="text-align: center; color: #bbb; padding: 60px 0;">
        暂无分析结果，请先执行分析
      </div>
    </el-card>
  </div>
</template>

<script>
import { Message, MessageBox } from 'element-ui'
import echarts from 'echarts'

const TASKS_KEY = 'offline_analysis_tasks'
const ANALYSIS_KEY = 'offline_analysis_result'

export default {
  name: 'OffLineDataAnalysis',
  data() {
    return {
      // 任务管理
      taskList: [],
      showCreateTask: false,
      editTaskId: null,
      taskForm: {
        name: '',
        script: null,
        executors: 4,
        memory: 8,
        framework: 'SparkSQL',
        enableSharding: true,
        schedule: ['02:00:00', '02:30:00'],
      },
      taskRules: {
        name: [{ required: true, message: '请输入任务名称', trigger: 'blur' }],
        script: [{ required: true, message: '请上传Python脚本', trigger: 'change' }],
        executors: [{ type: 'number', min: 4, message: '最少4个Executor', trigger: 'change' }],
        memory: [{ type: 'number', min: 8, message: '最少8GB内存', trigger: 'change' }],
        framework: [{ required: true, message: '请选择计算框架', trigger: 'change' }],
        schedule: [{ type: 'array', required: true, message: '请选择定时调度时间', trigger: 'change' }]
      },
      // 算法配置
      algoConfig: {
        method: 'K-Means',
        k: 5,
        iterations: 20,
        fields: ['电流', '电压', '运行时长']
      },
      analyzing: false,
      // 结果可视化
      analysisResult: null
    }
  },
  mounted() {
    this.loadTasks()
    this.loadAnalysisResult()
    this.$nextTick(this.renderHeatmap)
  },
  watch: {
    analysisResult() {
      this.$nextTick(this.renderHeatmap)
    }
  },
  methods: {
    // 任务管理
    loadTasks() {
      const tasks = JSON.parse(localStorage.getItem(TASKS_KEY) || '[]')
      this.taskList = tasks
    },
    saveTasks() {
      localStorage.setItem(TASKS_KEY, JSON.stringify(this.taskList))
    },
    resetTaskForm() {
      this.editTaskId = null
      this.taskForm = {
        name: '',
        script: null,
        executors: 4,
        memory: 8,
        framework: 'SparkSQL',
        enableSharding: true,
        schedule: ['02:00:00', '02:30:00'],
      }
      if (this.$refs.taskForm) this.$refs.taskForm.resetFields()
    },
    handleScriptUpload(file) {
      this.taskForm.script = file
    },
    submitTaskForm() {
      this.$refs.taskForm.validate(valid => {
        if (!valid) return
        const newTask = {
          id: this.editTaskId || Date.now(),
          name: this.taskForm.name,
          script: this.taskForm.script,
          executors: this.taskForm.executors,
          memory: this.taskForm.memory,
          framework: this.taskForm.framework,
          enableSharding: this.taskForm.enableSharding,
          schedule: this.taskForm.schedule,
          createdAt: this.editTaskId
            ? this.taskList.find(t => t.id === this.editTaskId).createdAt
            : this.formatDate(new Date()),
          status: '待执行',
          progress: 0
        }
        if (this.editTaskId) {
          const idx = this.taskList.findIndex(t => t.id === this.editTaskId)
          this.$set(this.taskList, idx, newTask)
        } else {
          this.taskList.push(newTask)
        }
        this.saveTasks()
        this.showCreateTask = false
        this.resetTaskForm()
        Message.success('任务保存成功')
      })
    },
    editTask(row) {
      this.editTaskId = row.id
      this.taskForm = {
        name: row.name,
        script: row.script,
        executors: row.executors,
        memory: row.memory,
        framework: row.framework,
        enableSharding: row.enableSharding,
        schedule: row.schedule
      }
      this.showCreateTask = true
    },
    deleteTask(id) {
      MessageBox.confirm('确定要删除该任务吗？', '提示', { type: 'warning' })
        .then(() => {
          this.taskList = this.taskList.filter(t => t.id !== id)
          this.saveTasks()
          Message.success('删除成功')
        })
        .catch(() => {})
    },
    statusTagType(status) {
      switch (status) {
        case '运行中': return 'success'
        case '已完成': return 'info'
        case '失败': return 'danger'
        case '待执行': return 'warning'
        default: return ''
      }
    },
    progressStatus(status) {
      switch (status) {
        case '运行中': return 'active'
        case '已完成': return 'success'
        case '失败': return 'exception'
        default: return 'normal'
      }
    },
    formatDate(date) {
      const d = new Date(date)
      return `${d.getFullYear()}-${(d.getMonth()+1).toString().padStart(2,'0')}-${d.getDate().toString().padStart(2,'0')} ${d.getHours().toString().padStart(2,'0')}:${d.getMinutes().toString().padStart(2,'0')}`
    },

    // 算法分析
    runAnalysis() {
      if (this.analyzing) return
      this.analyzing = true
      setTimeout(() => {
        // mock 生成分析结果
        const months = ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月']
        const heatmapData = months.map((m, i) => ({
          month: m,
          value: Math.round(300 + Math.random() * 500 + 200 * Math.sin(i/12 * Math.PI * 2))
        }))
        const confidence = months.map((m, i) => ({
          month: m,
          faults: Math.round(10 + Math.random() * 10 + 10 * Math.cos(i/12 * Math.PI * 2)),
          confidence: Math.round(70 + Math.random() * 30)
        }))
        this.analysisResult = { heatmapData, confidence }
        localStorage.setItem(ANALYSIS_KEY, JSON.stringify(this.analysisResult))
        this.analyzing = false
        Message.success('分析完成，结果已生成')
      }, 1200)
    },
    loadAnalysisResult() {
      const result = localStorage.getItem(ANALYSIS_KEY)
      if (result) {
        this.analysisResult = JSON.parse(result)
      }
    },
    renderHeatmap() {
      if (!this.analysisResult || !this.$refs.heatmap) return
      const chart = echarts.init(this.$refs.heatmap)
      chart.setOption({
        tooltip: { trigger: 'axis' },
        xAxis: { type: 'category', data: this.analysisResult.heatmapData.map(d => d.month) },
        yAxis: { type: 'value', name: '能耗' },
        series: [{
          name: '能耗',
          type: 'heatmap',
          data: this.analysisResult.heatmapData.map((d, i) => [i, 0, d.value]),
          label: { show: true, formatter: '{@[2]}' },
          emphasis: { itemStyle: { shadowBlur: 10, shadowColor: 'rgba(0,0,0,0.5)' } }
        }],
        visualMap: {
          min: 0,
          max: 1000,
          calculable: true,
          orient: 'horizontal',
          left: 'center',
          bottom: '10%'
        },
        grid: { top: 40, left: 60, right: 40, bottom: 60 }
      })
      window.addEventListener('resize', () => chart.resize())
    },
    exportReport() {
      if (!this.analysisResult) return
      // 导出为 txt
      let content = '设备年均故障高发期预测报告\n\n'
      content += '月份\t预测故障数\t置信度\n'
      this.analysisResult.confidence.forEach(row => {
        content += `${row.month}\t${row.faults}\t${row.confidence}%\n`
      })
      content += '\n分析说明：本报告基于K-Means聚类算法，结合设备能耗模式与历史故障数据，预测年均故障高发期及置信度，仅供参考。'
      const blob = new Blob([content], { type: 'text/plain;charset=utf-8' })
      const link = document.createElement('a')
      link.href = URL.createObjectURL(blob)
      link.download = '设备年均故障高发期预测报告.txt'
      link.click()
      Message.success('报告已导出')
    }
  }
}
</script>

<style scoped>
.offline-analysis {
  max-width: 1200px;
  margin: 0 auto;
  padding: 24px 0;
}
.box-card {
  margin-bottom: 24px;
}
</style>
